{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Interpreting SVHN Training with SGDNoise"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The gradient noise of SGD is considered crucial to the generalization performaces of deep learning models. However, in SGDNoise, authors propose that \"noises in classes different from the SGD noise can also effectively regularize gradient descent.\" This notebook trains a VGG11 model using small SVHN dataset. Three different training methods are conducted: Stochastic Gradient Descenet (SGD), Gradient Descent (GD), and Bernoulli Gradient Descent (BGD). Results show that an algorithm (for example BGD) that performs noisy gradient descent can generalize as SGD. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import paddle\n",
    "import paddle.fluid as fluid\n",
    "import tarfile, pickle, itertools\n",
    "import paddle.fluid.dygraph.nn as nn\n",
    "import random\n",
    "import gzip\n",
    "from struct import unpack\n",
    "import numpy as np\n",
    "import os"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you haven't done so, please first download the cropped SVHN training [dataset](http://ufldl.stanford.edu/housenumbers/train_32x32.mat) and [testing](http://ufldl.stanford.edu/housenumbers/test_32x32.mat) dataset.\n",
    "\n",
    "SVHN is a real-world image dataset for Street View House Numbers. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import scipy.io as sio\n",
    "import os\n",
    "\n",
    "def svhn(data_dir='./'):\n",
    "    print('loading SVHN dataset ......')\n",
    "    data = []\n",
    "    trainset = sio.loadmat(os.path.join(data_dir, 'train_32x32.mat'))\n",
    "    images = trainset['X'].transpose([3,2,0,1])\n",
    "    labels = trainset['y'].reshape(-1,1)\n",
    "    labels = labels - 1\n",
    "    data.append((images[0:70000], labels[0:70000]))\n",
    "    \n",
    "    testset = sio.loadmat(os.path.join(data_dir, 'test_32x32.mat'))\n",
    "    images = testset['X'].transpose([3,2,0,1])\n",
    "    labels = testset['y'].reshape(-1,1)\n",
    "    labels = labels - 1\n",
    "    data.append((images[0:25000], labels[0:25000]))\n",
    "    return tuple(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define a VGG11 architecture for Small SVHN dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from paddle.fluid.layer_helper import LayerHelper\n",
    "from paddle.fluid.dygraph.nn import Conv2D, Pool2D, BatchNorm, Linear\n",
    "from paddle.fluid.dygraph.base import to_variable\n",
    "\n",
    "class vgg_block(fluid.dygraph.Layer):\n",
    "    def __init__(self, name_scope, num_convs, in_channels, out_channels):\n",
    "        super(vgg_block, self).__init__(name_scope)\n",
    "        self.conv_list = []\n",
    "        for i in range(num_convs):\n",
    "            conv_layer = self.add_sublayer('conv_' + str(i), Conv2D(num_channels=in_channels, \n",
    "                                        num_filters=out_channels, filter_size=3, padding=1, act='relu'))\n",
    "            self.conv_list.append(conv_layer)\n",
    "            in_channels = out_channels\n",
    "        self.pool = Pool2D(pool_stride=2, pool_size = 2, pool_type='max')\n",
    "    def forward(self, x):\n",
    "        for item in self.conv_list:\n",
    "            x = item(x)\n",
    "        return self.pool(x)\n",
    "    \n",
    "class VGG11(fluid.dygraph.Layer):\n",
    "    def __init__(self, conv_arch=((1, 64), \n",
    "                                (1, 128), (2, 256), (2, 512), (2, 512))):\n",
    "        super(VGG11, self).__init__()\n",
    "        self.vgg_blocks=[]\n",
    "        iter_id = 0\n",
    "        in_channels = [3, 64, 128, 256, 512, 512]\n",
    "        for (num_convs, num_channels) in conv_arch:\n",
    "            block = self.add_sublayer('block_' + str(iter_id), \n",
    "                    vgg_block(self.full_name(), num_convs, in_channels=in_channels[iter_id], \n",
    "                              out_channels=num_channels))\n",
    "            self.vgg_blocks.append(block)\n",
    "            iter_id += 1\n",
    "        self.fc1 = Linear(input_dim=512, output_dim=512,\n",
    "                      act='relu')\n",
    "        self.drop1_ratio = 0.5\n",
    "        self.fc2= Linear(input_dim=512, output_dim=512,\n",
    "                      act='relu')\n",
    "        self.drop2_ratio = 0.5\n",
    "        self.fc3 = Linear(input_dim=512, output_dim=10)\n",
    "    def forward(self, x, y=None):\n",
    "        for item in self.vgg_blocks:\n",
    "            x = item(x)\n",
    "        x = fluid.layers.reshape(x, [x.shape[0], -1])\n",
    "        x = fluid.layers.dropout(self.fc1(x), self.drop1_ratio)\n",
    "        x = fluid.layers.dropout(self.fc2(x), self.drop2_ratio)\n",
    "        x = self.fc3(x)\n",
    "        return x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define the dataloader, in which images are scaled to [0,1]."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def data_loader(data, batch_size=100, shuffle=False):\n",
    "    images = data[0].astype('float32') / 255.0\n",
    "    labels = data[1].astype('int64')\n",
    "    assert images.shape[0] == labels.shape[0], \\\n",
    "        'length of images({}) should be the same as labels({})'.format(images.shape[0], labels.shape[0])\n",
    "    data_ids = list(range(labels.shape[0]))\n",
    "\n",
    "    def generator():\n",
    "        if shuffle:\n",
    "            random.shuffle(data_ids)\n",
    "        batch_image, batch_label = [], []\n",
    "        for i in data_ids:\n",
    "            batch_image.append(images[i])\n",
    "            batch_label.append(labels[i])\n",
    "            if len(batch_label) == batch_size:\n",
    "                yield np.array(batch_image), np.array(batch_label)\n",
    "                batch_image, batch_label = [], []\n",
    "        if len(batch_label) > 0:\n",
    "            yield np.array(batch_image), np.array(batch_label)\n",
    "\n",
    "    return generator"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To reduce the training time, 25000 images from the original test set are used as the training set, and 70000 images from the original training set are used as the test set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loading SVHN dataset ......\n"
     ]
    }
   ],
   "source": [
    "test_dataset, train_dataset = svhn()\n",
    "train_loader = data_loader(train_dataset, batch_size=100, shuffle=True)\n",
    "test_loader = data_loader(test_dataset, batch_size=100, shuffle=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we self-defined a loss function that apply masks to cross entropy loss."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def CEwithMask(input, target, mask=None):\n",
    "    \"\"\"mask should have identity mean\"\"\"\n",
    "    input = fluid.layers.log_softmax(input, axis=-1)\n",
    "    onehot_target = fluid.layers.one_hot(target, 10)\n",
    "    loss = fluid.layers.elementwise_mul(input, onehot_target)\n",
    "    loss = - fluid.layers.reduce_sum(loss, dim=1, keep_dim=True)#- input[]\n",
    "    if mask is not None:\n",
    "        loss = loss * mask\n",
    "    loss = fluid.layers.mean(loss)\n",
    "    return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define the trainer and tester."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "def tester(model, data_loader, place=fluid.CPUPlace()):\n",
    "    model.eval()\n",
    "    correct, total = 0, 0\n",
    "    with fluid.dygraph.guard(place), fluid.dygraph.no_grad():\n",
    "        for batch_id, (batch_image, batch_label) in enumerate(data_loader(), 1):\n",
    "            batch_image = fluid.dygraph.to_variable(batch_image)\n",
    "            batch_label = fluid.dygraph.to_variable(batch_label.reshape(-1,))\n",
    "            predict = fluid.layers.argmax(model(batch_image), axis=1)\n",
    "            correct += fluid.layers.reduce_sum(fluid.layers.equal(predict, batch_label).astype('int32')).numpy()[0]\n",
    "            total += batch_label.shape[0]\n",
    "    return correct / total\n",
    "\n",
    "\n",
    "def trainer(train_type, iterations=10000, lr=0.05, batch_size=100, no_cuda=False, test_iter=10):\n",
    "    if no_cuda:\n",
    "        place = fluid.CPUPlace()\n",
    "    else:\n",
    "        place = fluid.CUDAPlace(0)\n",
    "    \n",
    "    test_accuracy = list()\n",
    "    iter = 0\n",
    "    with fluid.dygraph.guard(place):\n",
    "        model = VGG11()\n",
    "        model.train()\n",
    "\n",
    "        n_batches = np.ceil(train_dataset[0].shape[0] / batch_size)\n",
    "        optimizer = fluid.optimizer.SGDOptimizer(learning_rate=lr, parameter_list=model.parameters())\n",
    "        \n",
    "        if train_type == 'sgd':\n",
    "            epochs = int(iterations // n_batches)\n",
    "        elif train_type == 'gd' or train_type == 'bgd':\n",
    "            epochs = iterations\n",
    "        \n",
    "        prob = 1 / n_batches\n",
    "        best_acc = 0\n",
    "        for epoch_id in range(1, epochs + 1):\n",
    "            l_total = None\n",
    "            total_loss = 0\n",
    "            if train_type == 'gd' or train_type == 'bgd':\n",
    "                model.clear_gradients()\n",
    "            for batch_id, (batch_image, batch_label) in enumerate(train_loader(), 1):\n",
    "                batch_image = fluid.dygraph.to_variable(batch_image)\n",
    "                batch_label = fluid.dygraph.to_variable(batch_label)\n",
    "                \n",
    "                predict = model(batch_image, batch_label)\n",
    "                \n",
    "                if train_type == 'sgd':\n",
    "                    avg_loss = CEwithMask(predict, batch_label, mask=None)\n",
    "                    model.clear_gradients()\n",
    "                    avg_loss.backward()\n",
    "                    \n",
    "                    if iter % test_iter == 0:\n",
    "                        accuracy = tester(model, test_loader, place)\n",
    "                        print(accuracy)\n",
    "                        test_accuracy.append((accuracy, iter))\n",
    "                        model.train()\n",
    "                    iter += 1\n",
    "                    \n",
    "                elif train_type == 'gd':\n",
    "                    avg_loss = CEwithMask(predict, batch_label, mask=None) \n",
    "                    if batch_id % 100 == 0:\n",
    "                        print('loss', avg_loss.numpy()[0])\n",
    "                    avg_loss.backward()\n",
    "                    l = optimizer.backward(avg_loss, parameter_list = None)\n",
    "\n",
    "                    if l_total is None:\n",
    "                        l_total = [(tup[0], tup[1]/n_batches) for tup in l]\n",
    "                    else:\n",
    "                        for i, param in enumerate(l):\n",
    "                            l_total[i] = (l_total[i][0], l_total[i][1] + l[i][1]/n_batches)\n",
    "                            \n",
    "                elif train_type == 'bgd':\n",
    "                    mask = fluid.layers.uniform_random(batch_label.shape, dtype=\"float32\")\n",
    "                    mask = fluid.layers.cast(mask > 1-prob, dtype='float32')\n",
    "                    mask *= n_batches\n",
    "                    \n",
    "                    avg_loss = CEwithMask(predict, batch_label, mask=mask)\n",
    "                    print('loss', avg_loss.numpy()[0])\n",
    "                    \n",
    "                    avg_loss.backward()\n",
    "                    l = optimizer.backward(avg_loss, parameter_list = None)\n",
    "                    \n",
    "                    if l_total is None:\n",
    "                        l_total = [(tup[0], tup[1]/n_batches) for tup in l]\n",
    "                    else:\n",
    "                        for i, param in enumerate(l):\n",
    "                            l_total[i] = (l_total[i][0], l_total[i][1] + l[i][1]/n_batches)\n",
    "                    \n",
    "                if train_type == 'sgd':\n",
    "                    optimizer.minimize(avg_loss)\n",
    "                    \n",
    "            if train_type == 'gd' or train_type == 'bgd':\n",
    "                optimizer.apply_gradients(l_total)\n",
    "                if iter % test_iter == 0:\n",
    "                    accuracy = tester(model, test_loader, place)\n",
    "                    print(accuracy)\n",
    "                    test_accuracy.append((accuracy, iter))\n",
    "                    model.train()\n",
    "                iter += 1\n",
    "\n",
    "    test_accuracy = np.array(test_accuracy)\n",
    "    return test_accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "sgd_accuracies = trainer(train_type='sgd', iterations=15000, lr=0.05, batch_size=100, no_cuda=False, test_iter=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "gd_accuracies = trainer(train_type='gd', iterations=15000, lr=0.05, batch_size=100, no_cuda=False, test_iter=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "bgd_accuracies = trainer(train_type='bgd', iterations=15000, lr=0.05, batch_size=100, no_cuda=False, test_iter=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the cells below, we print the best test accuracies and plot testing accuracies for three training procedures. We observe that the best accuracies for SGD and BGD are close, and both are better than GD. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best SGD Testing Accuracy: 0.8726285714285714\n",
      "Best GD Testing Accuracy: 0.8474428571428572\n",
      "Best BGD Testing Accuracy: 0.8690857142857142\n"
     ]
    }
   ],
   "source": [
    "print('Best SGD Testing Accuracy:', max([tup[0] for tup in sgd_accuracies]))\n",
    "print('Best GD Testing Accuracy:', max([tup[0] for tup in gd_accuracies]))\n",
    "print('Best BGD Testing Accuracy:', max([tup[0] for tup in bgd_accuracies]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7fbcb626f350>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.plot(np.arange(0, 15000, 10), [tup[0] for tup in bgd_accuracies], linewidth=1, label = 'bgd')\n",
    "plt.plot(np.arange(0, 15000, 10), [tup[0] for tup in gd_accuracies], linewidth=1,label = 'gd')\n",
    "plt.plot(np.arange(0, 15000, 10), [tup[0] for tup in sgd_accuracies],  linewidth=1,label = 'sgd')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.8690857142857142\n",
      "0.8474428571428572\n",
      "0.8726285714285714\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "bgd = np.load('bgd_svhn_sgd.npy')[:15000]\n",
    "gd = np.load('gd_svhn_sgd.npy')[:15000]\n",
    "sgd = np.load('sgd_svhn_sgd.npy')[:15000]\n",
    "print(max([tup[0] for tup in bgd]))\n",
    "print(max([tup[0] for tup in gd]))\n",
    "print(max([tup[0] for tup in sgd]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7fbcb72bdc50>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.plot(np.arange(0, 15000, 10), [tup[0] for i, tup in enumerate(bgd) if i % 10 == 0], linewidth=1, label = 'bgd')\n",
    "plt.plot(np.arange(0, 15000, 10), [tup[0] for i, tup in enumerate(gd) if i % 10 == 0], linewidth=1,label = 'gd')\n",
    "plt.plot(np.arange(0, 15000, 10), [tup[0] for i, tup in enumerate(sgd) if i % 10 == 0],  linewidth=1,label = 'sgd')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
